import collections
import datetime
from collections import Iterable
from typing import Any, List, Tuple

DZ = 300


def parse__2_sac_model(dict__, cls):
    obj = cls()
    obj.__dict__ = dict__
    return obj


def from_query_set_get_model(query_set, cls_, need_cols = []):
    obj = cls_()

    for col_ in query_set:
        print("col _ {} val_ {}".format(col_, query_set.get(col_)))
        setattr(obj, col_, query_set.get(col_))
    # for col_ in need_cols:
    #     if col_ in query_set:
    #         setattr(obj, col_,query_set.get(col_))
    # return obj
    # obj.__dict__
    return obj
    pass


def regroup_db_res_2_pre_json_data(db_dict_lis: list, allowed_cols=None, log_unmatch_col=False, ingore_cols=set()):
    allowed_all = False
    if not allowed_cols:
        allowed_all = True

    losed_col_set = set()
    standard_pre_json_object = dict()
    for _temp_r in db_dict_lis:

        for _col in _temp_r.keys():
            if (allowed_all or _col in allowed_cols) and _col not in ingore_cols:
                # 初始化返回数据
                if _col not in standard_pre_json_object:
                    standard_pre_json_object[_col] = list()
                standard_pre_json_object[_col].append(_temp_r[_col])
            else:
                losed_col_set.add(_col)

    return standard_pre_json_object


# 注入返回结果是否正确的信息
def generate_success_dict(web_res):
    if not type(web_res) == dict:
        return
    web_res['api_call'] = 1
    return web_res


def generate_fail_dict(web_res):
    if not type(web_res) == dict:
        return
    web_res['api_call'] = 0
    return web_res


def wrapper_res_dict(web_res, fail: bool):
    return generate_success_dict(web_res) if not fail else generate_fail_dict(web_res)


def generate_message_dict_4_fail(code: int or str = 500, message=''):
    return generate_fail_dict({'code': code, 'message': message})


def generate_right_date_equence(start_date: str or int, end_date: str or int, default_size: int, input_date_format: str,
                                out_date_format: str = None) -> \
        Tuple[Any, Any]:
    """ 根据当前时间生成默认的数据 """
    if default_size:
        default_size = int(default_size)
    import datetime
    strptime, strftime = datetime.datetime.strptime, datetime.datetime.strftime
    if start_date:
        start_date = str(start_date)
    if end_date:
        end_date = str(end_date)
    if start_date and end_date:
        return strptime(start_date, input_date_format).date(), strptime(end_date, input_date_format).date()
    if not start_date and not end_date:
        end_date = strftime(datetime.datetime.now(), input_date_format)
    # 返回时需要转化为date
    one_date, other_date = ['', '']
    if not default_size:
        shift_date_i_ = max(DZ, default_size if default_size else DZ)
    else:
        shift_date_i_ = default_size
    if end_date:
        shift_date_i_ = -1 * shift_date_i_
        et_ = strptime(str(end_date), input_date_format)
        one_date = et_
    else:
        st_ = strptime(str(start_date), input_date_format)
        one_date = st_

    shift_date_ = datetime.timedelta(days=shift_date_i_)

    # BASE_FORMAT = "%Y-%m-%d %H:%m:%s"
    # 转化为标准的date格式
    other_date = one_date + shift_date_

    # 互换两个大的位置
    if one_date > other_date:
        td = one_date
        one_date = other_date
        other_date = td
    # 输出的时
    return one_date.date(), other_date.date()

default_page_size = 150
def paginator_sql(cur_num  = 1, page_size  = default_page_size , all = False, **kwargs):

    if 'page_size' in kwargs:
        page_size = kwargs['page_size']
    if 'cur_num' in kwargs:
        cur_num = kwargs['cur_num']
    if 'all' in kwargs:
        all = kwargs['all']

    if cur_num == None:
        cur_num  = -1
    if page_size == None:
        page_size = default_page_size
    if all:
        page_size = 2000
    cur_num = int(cur_num)
    page_size = int(page_size)

    max_page_size = 10000
    page_size = min(max_page_size, page_size)
    cur_num = max(1, cur_num)
    print("limit {} , {}".format((cur_num-1)*page_size,page_size))
    return {"sql":"limit {} , {}".format((cur_num-1)*page_size,page_size),"size":page_size,"cur_page":cur_num}


def append_distinct_2_res(tmp_data: List, tmp_res):
    import random
    for t_d_ in tmp_data:
        if t_d_ not in tmp_res:

            pos = random.randint(0, max(len(tmp_data), 0))
            # tmp_res.append(t_d_)
            tmp_res.insert(pos, t_d_)


def generate_mutil_or_reg(kws ):
    reg = ""
    for kw_ in kws:
        reg += kw_ + "|"

    return reg[:-1] if len(reg) > 0 else reg


def generate_mutil_or_like(main_col , kws ,single = False, need_where = False, need_and = False, wrapper = False):
    like_sql  = " "
    if isinstance(kws, collections.Iterable) and not isinstance(kws, str):
        if single:
            raise Exception("不接受单个对象")
        for kw_ in kws:
            like_sql += main_col + " like '%{}%' or ".format(kw_)
    elif isinstance(kws, str) or isinstance(kws, int):
        like_sql += main_col + " like '%{}%' or ".format(kws)
    has_val = True if len(like_sql) > 3 else False
    if not has_val:
        return " WHERE 1=1 " if need_where else "" + like_sql
    print((" WHERE 1=1 " if need_where else " ") + (" AND " if need_and else " ") + like_sql[:-3] if len(like_sql) > 3 else like_sql)
    sql_ = like_sql[:-3] if len(like_sql) > 3 else like_sql
    if wrapper:
        sql_ = " ({}) ".format(sql_)
    return (" WHERE " if need_where else " ") + (" AND " if need_and else " ") +sql_

if __name__ == '__main__':
    start_date = "20190101"
    end_date = "20190201"
    dz = 7
    i_f = "%Y%m%d"
    rst, ret = generate_right_date_equence(start_date, end_date, dz, i_f)
    assert rst == datetime.date(2019, 1, 1) and ret == datetime.date(2019, 2, 1)

    rst, ret = generate_right_date_equence("20190101", None, dz, i_f)
    assert rst == datetime.date(2019, 1, 1) and ret == datetime.date(2019, 1, 11)

    rst, ret = generate_right_date_equence(None, "20190111", dz, i_f)
    assert rst == datetime.date(2019, 1, 1) and ret == datetime.date(2019, 1, 11)

    rst, ret = generate_right_date_equence(None, None, dz, i_f)
    assert rst == datetime.date(2019, 12, 22) and ret == datetime.date(2020, 1, 1)
